#include "usart.h"
#include <libopencm3/stm32/gpio.h>
#include <libopencm3/stm32/usart.h>
#include <libopencm3/stm32/dma.h>
#include <libopencm3/stm32/f4/rcc.h>
#include <stddef.h>
#include <libopencm3/stm32/f4/nvic.h>
// 引脚相关宏定义
#define USART1_TX_PIN GPIO9
#define USART1_RX_PIN GPIO10
#define USART2_TX_PIN GPIO2
#define USART2_RX_PIN GPIO3
// 引脚相关宏定义
#define USART1_TX_PIN GPIO9
#define USART1_RX_PIN GPIO10
#define USART2_TX_PIN GPIO2
#define USART2_RX_PIN GPIO3

// 接收缓冲区大小
#define RX_BUFFER_SIZE 256

// 每个串口的接收缓冲区结构
typedef struct {
    uint8_t buffer[RX_BUFFER_SIZE];
    volatile uint8_t head;
    volatile uint8_t tail;
    char line_buffer[RX_BUFFER_SIZE];
    bool line_ready;
} UsartRxBuffer;

// 为每个串口分配缓冲区（支持USART1和USART2）
static UsartRxBuffer rx_buffers[2] = {0};

// 获取串口对应的缓冲区索引
static int get_buffer_index(uint32_t usart) {
    if (usart == USART1) return 0;
    if (usart == USART2) return 1;
    return -1;
}

// 初始化串口参数结构体，设置默认值
UsartParameters usart_default_params(void) {
    UsartParameters params = {
            .baudrate = 115200,
            .databits = 8,
            .stopbits = USART_STOPBITS_1,
            .parity = USART_PARITY_NONE,
            .flow_control = USART_FLOWCONTROL_NONE,
            .mode = USART_MODE_TX_RX
    };
    return params;
}

// 自动初始化指定串口，使用默认参数
void usart_auto_init(uint32_t usart) {
    UsartParameters params = usart_default_params();
    usart_manual_init(usart, &params);
}

// 手动初始化指定串口，使用自定义参数
void usart_manual_init(uint32_t usart, const UsartParameters *params) {
    // 根据传入的串口使能对应的GPIO和USART时钟
    switch (usart) {
        case USART1:
            rcc_periph_clock_enable(RCC_GPIOA);
            rcc_periph_clock_enable(RCC_USART1);
            // 配置USART1的引脚
            gpio_mode_setup(GPIOA, GPIO_MODE_AF, GPIO_PUPD_NONE, USART1_TX_PIN);
            gpio_mode_setup(GPIOA, GPIO_MODE_AF, GPIO_PUPD_NONE, USART1_RX_PIN);
            gpio_set_af(GPIOA, GPIO_AF7, USART1_TX_PIN);
            gpio_set_af(GPIOA, GPIO_AF7, USART1_RX_PIN);
            break;
        case USART2:
            rcc_periph_clock_enable(RCC_GPIOA);
            rcc_periph_clock_enable(RCC_USART2);
            // 配置USART2的引脚
            gpio_mode_setup(GPIOA, GPIO_MODE_AF, GPIO_PUPD_NONE, USART2_TX_PIN);
            gpio_mode_setup(GPIOA, GPIO_MODE_AF, GPIO_PUPD_NONE, USART2_RX_PIN);
            gpio_set_af(GPIOA, GPIO_AF7, USART2_TX_PIN);
            gpio_set_af(GPIOA, GPIO_AF7, USART2_RX_PIN);
            break;
        default:
            break;
    }

    // 配置串口参数
    usart_set_baudrate(usart, params->baudrate);
    usart_set_databits(usart, params->databits);
    usart_set_stopbits(usart, params->stopbits);
    usart_set_parity(usart, params->parity);
    usart_set_flow_control(usart, params->flow_control);
    usart_set_mode(usart, params->mode);

    // 使能串口
    usart_enable(usart);
}

// 发送一个字节
void usart_send_byte(uint32_t usart, uint8_t byte) {
    // 等待发送数据寄存器为空
    while (!(usart_get_flag(usart, USART_SR_TXE)));
    usart_send(usart, (uint16_t)byte);
}

// 发送字符串
void usart_send_string(uint32_t usart, const char *str) {
    while (*str) {
        usart_send_byte(usart, *str++);
    }
}

// 接收一个字节（阻塞式）
uint8_t usart_recv_byte(uint32_t usart) {
    // 等待接收数据寄存器非空
    while (!(usart_get_flag(usart, USART_SR_RXNE)));
    return (uint8_t)usart_recv(usart);
}

// 启用非阻塞接收
void usart_enable_nonblocking(uint32_t usart) {
    int idx = get_buffer_index(usart);
    if (idx < 0) return;

    // 使能接收中断
    usart_enable_rx_interrupt(usart);

    // 使能对应的NVIC中断
    if (usart == USART1) {
        nvic_enable_irq(NVIC_USART1_IRQ);
    } else if (usart == USART2) {
        nvic_enable_irq(NVIC_USART2_IRQ);
    }
}

// 检查是否有数据可用
bool usart_has_data(uint32_t usart) {
    int idx = get_buffer_index(usart);
    if (idx < 0) return false;

    return (rx_buffers[idx].head != rx_buffers[idx].tail);
}

// 尝试接收一个字节（非阻塞）
int usart_try_recv_byte(uint32_t usart) {
    int idx = get_buffer_index(usart);
    if (idx < 0 || !usart_has_data(usart)) {
        return -1;  // 无数据
    }

    uint8_t data = rx_buffers[idx].buffer[rx_buffers[idx].tail];
    rx_buffers[idx].tail = (rx_buffers[idx].tail + 1) % RX_BUFFER_SIZE;
    return data;
}

// 处理接收到的数据（构建行）
static void process_received_data(uint32_t usart, uint8_t data) {
    int idx = get_buffer_index(usart);
    if (idx < 0) return;

    UsartRxBuffer *buf = &rx_buffers[idx];

    // 将数据存入环形缓冲区
    uint8_t next_head = (buf->head + 1) % RX_BUFFER_SIZE;
    if (next_head != buf->tail) {  // 防止缓冲区溢出
        buf->buffer[buf->head] = data;
        buf->head = next_head;

        // 处理行缓冲
        static int line_index = 0;
        if (data == '\n' || line_index >= sizeof(buf->line_buffer) - 1) {
            buf->line_buffer[line_index] = '\0';
            buf->line_ready = true;
            line_index = 0;
        } else if (data != '\r') {  // 忽略回车符
            buf->line_buffer[line_index++] = data;
        }
    }
}

// 检查是否接收到完整行
bool usart_has_line(uint32_t usart) {
    int idx = get_buffer_index(usart);
    if (idx < 0) return false;

    return rx_buffers[idx].line_ready;
}

// 获取接收到的行
const char* usart_get_line(uint32_t usart) {
    int idx = get_buffer_index(usart);
    if (idx < 0) return NULL;

    rx_buffers[idx].line_ready = false;
    return rx_buffers[idx].line_buffer;
}

// USART1中断处理函数
void usart1_isr(void) {
    if (usart_get_flag(USART1, USART_SR_RXNE)) {
        uint8_t data = usart_recv(USART1);
        process_received_data(USART1, data);
    }
}

// USART2中断处理函数
void usart2_isr(void) {
    if (usart_get_flag(USART2, USART_SR_RXNE)) {
        uint8_t data = usart_recv(USART2);
        process_received_data(USART2, data);
    }
}

//// 示例
//int example(void) {
//    // 自动初始化USART1，使用默认参数
//    usart_auto_init(USART1);
//    usart_send_string(USART1, "USART1 auto initialized, using default settings.\r\n");
//
//    // 手动初始化USART2，自定义参数
//    UsartParameters custom_params = {
//            .baudrate = 9600,
//            .databits = 8,
//            .stopbits = USART_STOPBITS_1,
//            .parity = USART_PARITY_NONE,
//            .flow_control = USART_FLOWCONTROL_NONE,
//            .mode = USART_MODE_TX_RX
//    };
//    usart_manual_init(USART2, &custom_params);
//    usart_send_string(USART2, "USART2 manually initialized, using custom settings.\r\n");
//
//    while (1) {
//        // 主循环中可以进行数据的接收和发送操作
//        // 例如：
//        // uint8_t received_byte = usart_recv_byte(USART1);
//        // usart_send_byte(USART1, received_byte);
//    }
//
//    return 0;
//}